package com.bazaaroid.client.web.gwt.partnermodule.client.view.locations.impl;

import java.util.HashMap;
import java.util.Map;

import com.bazaaroid.client.web.gwt.partnermodule.client.dto.LocationDTO;
import com.bazaaroid.client.web.gwt.partnermodule.client.event.locations.handler.LocationViewHandler;
import com.bazaaroid.client.web.gwt.partnermodule.client.view.common.LoadingPanel;
import com.bazaaroid.client.web.gwt.partnermodule.client.view.common.TitleCommandBar;
import com.bazaaroid.client.web.gwt.partnermodule.client.view.locations.EditLocationEntryView;
import com.bazaaroid.client.web.gwt.partnermodule.client.view.locations.LocationEntryView;
import com.bazaaroid.client.web.gwt.partnermodule.client.view.locations.LocationsTabView;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.maps.client.InfoWindowContent;
import com.google.gwt.maps.client.MapWidget;
import com.google.gwt.maps.client.Maps;
import com.google.gwt.maps.client.control.LargeMapControl;
import com.google.gwt.maps.client.geom.LatLng;
import com.google.gwt.maps.client.overlay.Marker;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiTemplate;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.DecoratorPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;

public class LocationsTabViewImpl extends Composite implements LocationsTabView {

	@UiTemplate("LocationsTabView.ui.xml")
	interface LocationsTabViewUiBinder extends
			UiBinder<Widget, LocationsTabViewImpl> {
	}

	private static LocationsTabViewUiBinder uiBinder = GWT
			.create(LocationsTabViewUiBinder.class);

	private Presenter presenter;

	private LoadingPanel loadingPanel = new LoadingPanel(new Label("Loading"));
	private LoadingPanel savingPanel = new LoadingPanel(new Label("Loading"));
	private Map<LocationDTO, Widget> locationViews = new HashMap<LocationDTO, Widget>();
	private LocationViewHandler locationViewHandler;

	@UiField
	VerticalPanel locationListPanel;
	@UiField
	VerticalPanel mapPanel;

	private class NewLocationClickHandler implements ClickHandler {
		@Override
		public void onClick(ClickEvent event) {
			LocationDTO locationDTO = new LocationDTO();
			EditLocationEntryView editLocationEntryView = new EditLocationEntryView(
					LocationsTabViewImpl.this, locationDTO);
			locationListPanel.insert(editLocationEntryView, 0);
			locationViews.put(locationDTO, editLocationEntryView);
		}
	}

	public LocationsTabViewImpl() {
		initWidget(uiBinder.createAndBindUi(this));

		locationListPanel.add(loadingPanel);
		locationListPanel.add(savingPanel);

		TitleCommandBar titleBar = new TitleCommandBar("Locations Management");
		titleBar.addCommand("New Location", new NewLocationClickHandler());
		locationListPanel.add(titleBar);

		final LocationDTO locationDTO = new LocationDTO();
		locationDTO.setName("TC Usce");
		locationDTO.setLatitude("44.815249");
		locationDTO.setLongitude("20.436928");
		addEntryAtEnd(locationDTO);
		LocationDTO locationDTO2 = new LocationDTO();
		locationDTO2.setName("Knez Mihajlova");
		locationDTO2.setLatitude("44.816281");
		locationDTO2.setLongitude("20.458929");
		addEntryAtEnd(locationDTO2);

		Maps.loadMapsApi("", "2", false, new Runnable() {
			public void run() {
				// Open a map centered on TC Usce
				LatLng locationUsce = LatLng.newInstance(Double.parseDouble(locationDTO.getLatitude()), Double.parseDouble(locationDTO.getLongitude()));

				final MapWidget map = new MapWidget(locationUsce, 13);
				map.setSize("500px", "400px");
				map.setUIToDefault();
			    				
				// Add some controls for the zoom level
				map.addControl(new LargeMapControl());

				// Add a marker
				map.addOverlay(new Marker(locationUsce));

				// Add an info window to highlight a point of interest
				map.getInfoWindow().open(
						map.getCenter(),
						new InfoWindowContent(locationDTO.getName()));

				DecoratorPanel decorator = new DecoratorPanel();
			    decorator.add(map);
			    
				mapPanel.add(decorator);

			}
		});

	}

	public LocationViewHandler getLocationViewHandler() {
		return locationViewHandler;
	}

	public LoadingPanel getLoadingPanel() {
		return loadingPanel;
	}

	public LoadingPanel getSavingPanel() {
		return savingPanel;
	}

	public void addEntryAtStart(LocationDTO locationDTO) {
		LocationEntryView locationEntryView = new LocationEntryView(this,
				locationDTO);
		locationListPanel.insert(locationEntryView, 0);
		locationViews.put(locationDTO, locationEntryView);
	}

	public void addEntryAtEnd(LocationDTO locationDTO) {
		LocationEntryView locationEntryView = new LocationEntryView(this,
				locationDTO);
		locationListPanel.add(locationEntryView);
		locationViews.put(locationDTO, locationEntryView);
	}

	public void startEdit(LocationEntryView locationEntryView) {
		EditLocationEntryView editLocationEntryView = new EditLocationEntryView(
				locationEntryView);
		swapViews(locationEntryView, editLocationEntryView, locationEntryView
				.getLocationDTO());
	}

	public void endEdit(EditLocationEntryView editLocationEntryView,
			LocationEntryView locationEntryView) {
		swapViews(editLocationEntryView, locationEntryView, locationEntryView
				.getLocationDTO());
	}

	public void onLocationEntrySaved(LocationEntryView locationEntryView,
			EditLocationEntryView editLocationEntryView, LocationDTO locationDTO) {
		locationViewHandler.onLocationEntrySaved(locationDTO);
		if (locationEntryView != null) {
			locationEntryView.update();
			locationEntryView.getLocationsTabView().endEdit(
					editLocationEntryView, locationEntryView);
		} else {
			addEntryAtStart(locationDTO);
			editLocationEntryView.removeFromParent();
		}
	}

	public void swapViews(Widget oldView, Widget newView,
			LocationDTO locationDTO) {
		int index = locationListPanel.getWidgetIndex(oldView);
		oldView.removeFromParent();
		locationListPanel.insert(newView, index);
		locationViews.put(locationDTO, newView);
	}

	public void setPresenter(Presenter presenter) {
		this.presenter = presenter;
	}

	public Widget asWidget() {
		return this;
	}
}
